﻿using Akka.Actor;
using RestSharp;
using System;
using System.Linq;

namespace Akka.Ext.Http
{
    internal class MyActor : ReceiveActor
    {
        public MyActor(string baseUrl = null)
        {
            ReceiveAsync<RequestInfo>(async msg =>
            {
                RestClient client;
                if (!string.IsNullOrEmpty(baseUrl))
                {
                    client = new RestClient(baseUrl);
                }
                else
                {
                    client = new RestClient();
                }
                var req = new RestRequest(msg.Url)
                {
                    Method = msg.Method,
                    Timeout = msg.Timeout
                };

                if (msg.Header.Count > 0)
                {
                    foreach (var item in msg.Header)
                    {
                        req.AddHeader(item.Key, item.Value);
                    }
                }

                if (msg.Cookie.Count > 0)
                {
                    Uri uri = null;
                    if (!string.IsNullOrEmpty(baseUrl))
                    {
                        uri = new Uri(baseUrl);
                    }
                    else
                    {
                        uri = new Uri(msg.Url);
                    }
                    foreach (var item in msg.Cookie)
                    {
                        var cookie = new System.Net.Cookie(item.Key, item.Value);
#if !CORE
                        client.CookieContainer = new System.Net.CookieContainer();
#endif
                        client.CookieContainer.Add(uri, cookie);

                    }
                }

                if (msg.Query.Count > 0)
                {
                    foreach (var item in msg.Query)
                    {
                        req.AddQueryParameter(item.Key, item.Value);
                    }
                }

                if (msg.Form.Count > 0)
                {
                    foreach (var item in msg.Form)
                    {
                        req.AddParameter(item.Key, item.Value);
                    }
                }

                if (msg.Files.Count > 0)
                {
                    foreach (var item in msg.Files)
                    {
                        req.AddFile(item.Name, item.BytesData, item.FileName);
                    }
                }

                if (!string.IsNullOrEmpty(msg.JsonBody))
                {
#if CORE
                    req.AddStringBody(msg.JsonBody, DataFormat.Json);
#else
                    req.AddJsonBody(msg.JsonBody, "application/json"); //text/plain
#endif
                }

                var res = await client.ExecuteAsync(req);
                var info = new ResponseInfo();
                info.IsSuccess = res.IsSuccessful;
                if (!info.IsSuccess)
                {
                    info.Code = -2;
                    info.ErrorMessage = res.ErrorMessage;
                }
                else
                {
                    info.ContentType = res.ContentType;
                    if (info.ContentType == "text/plain" || info.ContentType == "application/json")
                    {
                        info.Data = res.Content;
                    }
                    else if (info.ContentType == "text/plain; charset=utf-8" || info.ContentType == "application/json; charset=utf-8")
                    {
                        info.Data = res.Content;
                    }
                    else //"application/octet-stream"
                    {
                        info.DataBytes = res.RawBytes;
                    }

#if CORE
                    var headerPar = res.ContentHeaders.FirstOrDefault(f => f.Name == "Content-Disposition");
#else
                    var headerPar = res.Headers.FirstOrDefault(f => f.Name == "Content-Disposition");
#endif
                    if (headerPar != null)
                    {
                        try
                        {
                            var filename = (string)headerPar.Value;
#if CORE
                            filename = filename.Split(';')[2].Trim().Split("filename*=UTF-8''")[1].Trim('"');
                            //info.FileName = System.Net.WebUtility.UrlDecode(filename);
#else
                            //filename = filename.Split(';')[1].Trim().Split('=')[1];
                            filename = filename.Split(';')[2].Trim().Split(new string[] { "filename*=UTF-8''" }, StringSplitOptions.RemoveEmptyEntries)[0].Trim('"');
                            //info.FileName = System.Web.HttpUtility.UrlDecode(filename);
#endif
                            info.FileName = System.Net.WebUtility.UrlDecode(filename);
                        }
                        catch
                        {

                        }
                    }

                }
#if CORE
                client.Dispose();
#endif
                Sender.Tell(info);

            });
        }
    }
}
